#pragma once
#include <string>
#include <memory>

#include "render_control.h"
#include "vertex.h"

namespace krryn{
namespace core{  class job_manager; }
namespace math{  class matrix; }
namespace view{  class shader_catalog; class shader; class camera; }
namespace scene{ class mesh; }
namespace system{
	class input_manager;
	class viewport_settings;

	// this class should be specialized by the rendering 
	// implemenation based on _RenderTag
	template<typename _RenderTag>
	class renderer{
	public:
		typedef std::auto_ptr<renderer> ptr;
		typedef _RenderTag render_tag;

		renderer(core::job_manager *a_Manager, 
			gui::render_control<_RenderTag> &a_Control) {}

		void begin_scene();
		void draw(scene::mesh &a_Mesh, const math::matrix &a_Transformation);
		void end_scene();

		void set_projection_matrix(const math::matrix &a_ProjectionMatrix);
		void set_camera(const view::camera &a_Camera);

		void attach_to(gui::render_control<_RenderTag> &a_Control);
	};

	// used to bind a control to the renderer in a type-safe way
	template
	<
		typename _RenderTag,
		typename _Renderer = renderer<_RenderTag>,
		typename _Control = gui::render_control<_RenderTag>
	>
	struct activate_t{
		_Control &m_Control;

		activate_t(_Renderer &a_Renderer, _Control &a_Control) 
			: m_Control(a_Control){
			activate();
		}

		void activate(){
			m_Control.activate();
		}

		~activate_t(){}
	};
}
}

#include "renderer_tags.h"
